[毎日Kotlin] Day12. SAM conversions(SAM変換)
はじめに
毎日Kotlinシリーズです。
このシリーズを初めての方はこちらです。「毎日Kotlin」はじめました | Developers.IO
問題
前回object式で書いていた部分を、SAM変換で書いてみよう。JavaコードをKotlinから呼ぶ時に楽になります。
When an object implements a SAM interface (one with a Single Abstract Method), you can pass a lambda instead. Read more about SAM-conversions.
In the previous example change an object expression to a lambda.
import java.util.* fun getList(): List<Int> { val arrayList = arrayListOf(1, 5, 2) Collections.sort(arrayList, { x, y -> TODO() }) return arrayList }
狙い
ここで考えて欲しい問題の意図はなんだろうか?
[毎日Kotlin] Day11. Object expressions(オブジェクト式)では、object式で無名クラスを作りました。
JavaコードをKotlinから呼ぶ場合、Abstractメソッドが1つのクラスを作る場合は、ラムダ式でかける便利機能があります。Koltinの場合はSAM変換ができません。なぜなら、最初からそういうコードを書ける機能があるから。
Calling Java from Kotlin - Kotlin Programming Language
Also note that this feature works only for Java interop; since Kotlin has proper function types, automatic conversion of functions into implementations of Kotlin interfaces is unnecessary and therefore unsupported.
解答例
import java.util.* fun getList(): List<Int> { val arrayList = arrayListOf(1, 5, 2) Collections.sort(arrayList, { x, y -> y - x }) return arrayList }
[毎日Kotlin] Day11. Object expressions(オブジェクト式)のobject式の解答と比較してみよう。
import java.util.* fun getList(): List<Int> { val arrayList = arrayListOf(1, 5, 2) Collections.sort(arrayList, object : Comparator<Int> { override fun compare(x: Int, y: Int) = y - x }) return arrayList }
メソッドが1つしかない場合に限定してるので、overrideするメソッド名を書く必要もなく、変数の個数と型があっていれば使えます。引数の個数だけあっていれば、型も省略可能。引数が1つの時は、itがデフォルトの引数名でつかえるので省略可能です。とても便利ですね。
[毎日Kotlin] Day5.Lambdas(ラムダ式) から、少し変えてます。
Androidの例
button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Log.v(TAG, v.getId() + "clicked"); } });
View.OnClickListenerは(v: View) -> Unitのラムダと同じとみれる(SAM変換)。
button.setOnClickListener { Log.v(TAG, "${it.id} clicked") }
メソッドが2つ以上ある場合はobject式を使いましょう。
あとがき
Day13.でまたお会いしましょう。